//
//  ELBluetoothManager.h
//  Elink
//
//  Created by iot_user on 2019/4/22.
//  Copyright © 2019 iot_iMac. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "ELPeripheralModel.h"
#import "ELSDKHeader.h"
#import "ELBlePublicTool.h"
#import "ELBleWifiDetailModel.h"


//MARK: Broadcast Equipment Protocol(广播设备协议)

@protocol ELBleBroadcastDelegate <NSObject>

@optional

/// Callback broadcast device data(回调广播设备数据)
/// @param cid cid
/// @param vid vid
/// @param pid pid
/// @param mac mac地址
/// @param data Custom data(自定义数据)
-(void)bleBroadcastWithCid:(int)cid vid:(int)vid pid:(int)pid mac:(NSString *_Nonnull)mac data:(NSData *_Nonnull)data;


@end


//MARK:Bluetooth Wifi protocol(蓝牙Wifi协议)
@protocol ElBleWifiDelegate <NSObject>

@optional

/**
 Callback Wifi details(回调Wifi详情)

 @param model 模型
 */
-(void)bleWifiReceiveWifiDetailModel:(ELBleWifiDetailModel *_Nonnull)model;

/**
Scan nearby wifi results(扫描附近wifi结果)

 @param count Number of nearby wifi(附近wifi数量)
 */
-(void)bleWifiReceiveScanedWifiCount:(int)count;

/**
 Callback Wifi MAC address(回调Wifi MAC地址)

 @param macData mac
 */
-(void)bleWifiReceiveWifiMacData:(NSData *_Nullable)macData;

/**
Callback WIFI password(回调WIFI密码)

 @param pwd password(密码)
 */
-(void)bleWifiReceiveWifiPwd:(NSString *_Nonnull)pwd;

/**
 Get DTIM interval (unit: ms)(获取DTIM间隔(单位:ms))

 @param interval Interval (unit: ms)(间隔(单位:ms))
 */
-(void)bleWifiReceiveWifiDTIMInterval:(NSInteger)interval;

/**
 Returns the visited URL(返回访问的url)

 @param url url
 */
-(void)bleWifiReceiveWifiAccessURL:(NSString *_Nonnull)url;

/**
  Call back wifi port number(回调wifi的端口号)

 @param port 端口号
 */
-(void)bleWifiReceiveWifiPort:(int)port;

/**
 Set or query the callback of the instruction execution result（设置指令蓝牙WIFI响应回调方法）
 只支持蓝牙Wifi部分枚举
 @param type Type of setting （设置的类型）
 @param result Set result（设置的结果）
 */
-(void)bleWifiReceiceResponseType:(ELInetSetCmdType)type result:(ELSetBluetoothResponseType)result;

/**
 获取会话码(deviceId)

 @param code (deviceId) deviceId(0 means no:为0时表示不存在)
 */
-(void)bleWifiReceiveWifiSNCode:(int)code;

@end

//MARK:蓝牙通用协议
@protocol ELBluetoothManagerDelegate <NSObject>
@optional

//Callback Bluetooth status（回调蓝牙状态）
-(void)bluetoothManagerUpdateBleState:(ELBluetoothState)state;
//Callback to scanned device（回调扫描到的设备）
-(void)bluetoothManagerScanedPeripherals:(NSArray<ELPeripheralModel *> *_Nonnull)peripherals;
//Special devices that can be bound in the callback, such as door locks（回调中扫描到的可以绑定的特殊设备，如门锁）
-(void)bluetoothManagerScanedCanBindSpecialPeripherals:(NSArray<ELPeripheralModel *> *_Nonnull)peripherals;
//Call back the scanned broadcast device(回调扫描到的广播设备)
-(void)bluetoothManagerScanedBroadcastPeripherals:(NSArray<ELPeripheralModel *> *_Nonnull)peripherals;

//Callback decrypted transparent data (A7 decrypted payload data)（回调解密后的数据(A7解密后payload数据)）
-(void)bluetoothManagerReceiveData:(NSData *_Nonnull)data deviceType:(ELSupportDeviceType)type;

/**
 Callback transparent transmission data(回调透传数据)

 @param data Transparent data transmission (this data cannot start with A6 or A7)(透传数据(此数据不能以A6或A7开头))
 */
-(void)bluetoothManagerReceivePassData:(NSData *_Nullable)data;


#pragma mark ============ A6 Set or query the callback of the instruction execution result（设置或查询指令执行结果的回调） ==============
/**
 Set or query the callback of the instruction execution result（设置指令蓝牙响应回调方法(握手指令除外)）

 @param type Type of setting （设置的类型）
 @param result Set result（设置的结果）
 */
-(void)bluetoothManagerReceiceResponseType:(ELInetSetCmdType)type result:(ELSetBluetoothResponseType)result;

/**
 Query module status callback（查询模块状态的回调）

 @param stateStrct 结构体
 */
-(void)bluetoothManagerReceiveMCUConnectedState:(struct ELMCUStateStruct)stateStrct;

/**
 Query the callback of the communication mode（查询通信模式的回调）

 @param type communication mode（通信模式）
 */
-(void)bluetoothManagerReceiveCommunicationMode:(ELCommunicationModeType)type;

/**
 Query the callback of automatic sleep time（查询自动睡眠时间的回调）

 @param sleetStrct Automatic sleep time(自动睡眠时间)
 */
-(void)bluetoothManagerReceiveAutoSleepTime:(struct ELAutoSleepTimeStruct)sleetStrct;

/**
 Query master-slave mode callback（查询主从模式回调）

 @param mode 模式
 0:Slave mode（从机模式）
 1:Host mode（主机模式）
 */
-(void)bluetoothManagerReceiveMCUMode:(int)mode;

/**
 Query the callback of UUID information（查询UUID信息的回调）

 @param uuid ELUUIDStruct
 */
-(void)bluetoothManagerReceiveUUID:(struct ELUUIDStruct)uuid;

/**
 Query the callback of the MAC address size endian（查询MAC地址大小端序的回调）

 @param type 类型
 0:Little endian（小端序）
 1:Big endian （大端序）
 */
-(void)bluetoothManagerReceiveMacAddressType:(int)type;

/**
 Query the callback of the Bluetooth serial port baud rate（查询蓝牙串口波特率的回调）

 @param rate Serial port baud rate（串口波特率）
 0:9600
 1:19200
 2:38400
 3:57600
 4:115200
 5:921600
 */
-(void)bluetoothManagerReceiveSerialPostBaudRate:(int)rate;

/**
 Query the callback of Bluetooth transmit power（查询蓝牙发射功率的回调）

 @param dbm Transmit power（发射功率）
 */
-(void)bluetoothManagerReceiveTransmittingPower:(int)dbm;

/**
 Query the callback of the Bluetooth connection interval（查询蓝牙连接间隔的回调）

 @param intervalStrct connection interval
 */
-(void)bluetoothManagerReceiveConnectInterval:(struct ELConnectIntervalStruct)intervalStrct;

/**
 Query the callback of the Bluetooth name（查询蓝牙名称的回调）

 @param name Bluetooth name（蓝牙名称）
 */
-(void)bluetoothManagerReceiceName:(NSString *_Nullable)name;

/**
 Query the callback of the Bluetooth broadcast interval（查询蓝牙广播间隔的回调）

 @param interval broadcast interval（广播间隔）
 */
-(void)bluetoothManagerReceiveBroadcastInterval:(int)interval;

/**
 Query the callback of the Bluetooth MAC address（查询蓝牙MAC地址的回调）

 @param macAddress MAC
 */
-(void)bluetoothManagerReceiveMACAddress:(NSString *_Nonnull)macAddress;

/**
 Query the callback of the software and hardware version number of the BM module（查询BM模块软硬件版本号的回调）

 @param bmVersion BM module software and hardware version number（BM模块软硬件版本号）
 */
-(void)bluetoothManagerReceiveBMVersion:(NSString *_Nonnull)bmVersion;

/**
 Query the callback of the MCU software and hardware version number（查询MCU软硬件版本号的回调）
 
 @param mcuVersion Callback of MCU software and hardware version number（MCU软硬件版本号的回调）
 */
-(void)bluetoothManagerReceiveMCUVersion:(NSString *_Nonnull)mcuVersion;

/**
 Query the callback of Bluetooth time（查询蓝牙时间的回调）

 @param date yyyy-MM-dd HH:mm:ss
 @param effective Time is invalid（时间有无效）
 0：effective（系统时间无效）
 1：invalid（系统时间有效）
 */
-(void)bluetoothManagerReceiveBluetoothDate:(NSString * _Nonnull)date effective:(BOOL)effective;

/**
 Query CID, VID, PID callback（查询CID,VID,PID的回调）

 @param did CID,VID,PID
 */
-(void)bluetoothManagerReceiveDID:(struct ELDIDStruct)did;

/**
 Query the callback of the battery status（查询电池状态的回调）

 @param battery Structure of battery charge status and charge percentage（电池充电状态和电量百分比的结构体）
 */
-(void)bluetoothManagerReceiveBattery:(struct ELBatteryStruct)battery;

/**
 * Query the callback of the device support unit（查询设备支持单位的回调）
 
 */
- (void)bluetoothManagerBackDeviceSupportUnitWithWeight:(NSArray<NSNumber *> *_Nullable)weightArray
                                                 Height:(NSArray<NSNumber *> *_Nullable)heightArray
                                            Temperature:(NSArray<NSNumber *> *_Nullable)temperatureArray
                                          BloodPressure:(NSArray<NSNumber *> *_Nullable)bloodPressureArray
                                               Pressure:(NSArray<NSNumber *> *_Nullable)pressureArray;

/// Blood glucose units supported by callback supported devices(回调支持的设备支持的血糖单位)
/// @param bloodSugarUnitArray Blood glucose unit array(血糖单位数组)
-(void)bluetoothManagerReceiveSupportBloodSugarUnitArray:(NSArray<NSNumber *>* _Nullable)bloodSugarUnitArray;


/**
 Set the result of the decoding key（设置解码密钥的结果）

 @param result 结果
 */
-(void)bluetoothManagerReceiveSetKeyResult:(BOOL)result;

/// Device authorization result(设备授权结果)
/// @param result 结果
-(void)bluetoothManagerReceiveDeviceAuthorizeResult:(ELBluetoothDeviceAuthorizeResult)result;


@end



NS_ASSUME_NONNULL_BEGIN

@interface ELBluetoothManager : NSObject

@property (nonatomic, assign, readonly) BOOL isOn;
//Bluetooth status（蓝牙状态）
@property (nonatomic, assign, readonly) ELBluetoothState state;
//version number（版本号）
@property (nonatomic, copy, readonly) NSString *bmVersion;
/**
 Save the model corresponding to the currently connected device
 保存当前连接的设备对应的模型
 */
@property (nonatomic, strong, readonly) ELPeripheralModel *peripheralModel;
//Bluetooth proxy(蓝牙代理)
@property (nonatomic, weak) id<ELBluetoothManagerDelegate> delegate;
//Bluetooth wifi proxy(蓝牙wifi代理)
@property (nonatomic, weak) id<ElBleWifiDelegate> bleWifiDelegate;
//Bluetooth Broadcast Device Protocol(蓝牙广播设备协议)
@property (nonatomic, weak) id<ELBleBroadcastDelegate> broadDelegate;


//设置appkey和secret
+(void)setAppKey:(NSString *)key appSecret:(NSString *)secret;

//
+(__kindof ELBluetoothManager * _Nonnull)shareManager;

/**
 Get the SDK version number
 获取SDK版本号
 */
-(NSString *)sdkVersion;

//Start scanning（开始扫描）
-(void)startScan;
//Stop scanning（停止扫描）
-(void)stopScan;
//Connecting device（连接设备）
-(void)connectPeripheral:(ELPeripheralModel *)peripheralModel;
//Disconnect device（断开设备）
-(void)disconnectPeripheral;

#pragma mark ============ 发送指令的3种方法 ==============
/**
 Shortcut method to send A6 data to BLE(发送A6数据给BLE的快捷方法)
 @param data The stitched payload part(拼接好的payload部分)
 */
-(void)sendCmdToMCUWithA6PayloadData:(NSData *)data;
/**
 Shortcut method of sending A7 data to MCU(发送A7数据给MCU的快捷方法)
 @param data The stitched payload part(拼接好的payload部分)
 @param type Equipment type(设备类型)
 */
-(void)sendCmdToMCUWithA7PayloadData:(NSData *)data deviceType:(ELSupportDeviceType)type;

/**
 General method of sending data (support data transparent transmission)(发送数据通用方法（支持数据透传）)
 
 @param data 数据
 */
-(void)sendData:(NSData *)data;

#pragma mark ============ Please rewrite the following methods in the subclass(请在子类重写以下方法) BEGIN==============

-(void)bluetoothUpdateState:(ELBluetoothState)state;

-(void)bluetoothScanPeripherals:(NSArray *)peripherals;


/**
Callback decrypted A7 transparent data (payload part), type device type( 回调解密后的A7透传数据(payload部分),type设备类型)
 */
-(void)bluetoothReceiveData:(NSData *)playload deviceType:(ELSupportDeviceType)type;

/**
 The special A6 data will only be received by the supported devices, and the complete A6 data (A6 is not encrypted) is passed to the subclass resolution.
 特殊的A6数据，只有支持的设备才会收到，将完整A6数据(A6不加密)传给子类解析
 ELSupportDeviceType support：
 ELSupportDeviceTypeBodyFatScale
 ELSupportDeviceTypeSmartLock
 */
-(void)bluetoothBackA6Data:(NSData *)data withClassId:(ELSupportDeviceType)type;

/**
 Callback to scan special devices that can be bound, such as door locks（回调扫描到的可以绑定的特殊设备，如门锁）
 */
-(void)bluetoothScanCanBindSpecialPeripherals:(NSArray *)peripherals;
//Call back the scanned broadcast device(回调扫描到的广播设备)
-(void)bluetoothScanBroadcastPeripherals:(NSArray *)peripherals;

/**
 Callback device basic information（回调设备基本信息）

 @param data Device basic information payload data (length is 16 bytes)（设备基本信息payload数据（长度为16个byte））
 */
-(void)bluetoothReceiveBasicInfoPayloadData:(NSData *)data;

///Callback transparent transmission data(回调透传数据)
/// @param data Transparent data(透传数据)
-(void)bluetoothReceivePassData:(NSData *)data;

//Broadcast equipment dedicated（广播设备专用）
/// Broadcast device data
/// @param cid cid
/// @param vid vid
/// @param pid pid
/// @param mac mac
/// @param data custom data(自定义数据)
-(void)bluetoothReceiveBroadcastDataWithCid:(int)cid vid:(int)vid pid:(int)pid mac:(NSString *_Nonnull)mac data:(NSData *_Nonnull)data;

#pragma mark ============ Please rewrite the following methods in the subclass(子类重写方法) END==============



#pragma mark ============ A6 Set or query instructions(设置或查询指令)  ==============

/**
 Get Bluetooth information(获取蓝牙信息)

 @param type ELInetGetCmdType （ELInetGetCmdTypeGetHandshake除外）
 */
-(void)getBluetoothInfoWithELInetGetCmdType:(ELInetGetCmdType)type;

/**
 Set the Bluetooth name(设置蓝牙名称)

 @param name Name, less than 14 bytes(名称,小于14个byte)
 */
-(void)setBluetoothName:(NSString * _Nonnull)name;

/**
 Set the broadcast interval(设置广播间隔时间)

 @param interval 20~2000
 */
-(void)setBroadcastInterval:(int)interval;


/**
 Set the connection interval 10(设置连接间隔)

 @param interval The interval range is 20~2000ms.(interval范围是20~2000ms)
 @param timeout  The timeout range is 1000~6000ms(timeout范围是1000~6000ms)
 @param latency  The latency range is 0~4(latency范围是0〜4)
 */
-(void)setConnectedInterval:(int)interval timeout:(int)timeout Latency:(int)latency;

/**
 Set the transmit power(设置发射功率)

 @param power The range of power is 0~10(power的范围是0~10)
 */
-(void)setTransmittingPower:(int)power;

/**
 Set the serial port baud rate(设置串口波特率)

 @param rate The range of rate is 0~5(rate的范围是0~5)
 0：9600
 1：19200
 2：38400
 3：57600
 4：115200
 5：921600
 */
-(void)setSerialPortbaudRate:(int)rate;

/**
 Set the MCU software and hardware version number(设置MCU软硬件版本号)

 @param hardware 硬件
 @param software 软件
 如果是:S1.1,S11.1,S111.1, .....
 请传：11,111,1111, ....
 @param type Manufacturer's own definition(厂家自己定义)
 @param year 年
 @param month 月
 @param day 日
 */
-(void)setMCUVersion:(unsigned int)hardware software:(unsigned int)software mcuType:(unsigned int)type year:(unsigned int)year month:(unsigned int)month day:(unsigned int)day;

/**
 Set the big endian or little endian of the Mac address in the broadcast manufacturer's custom data.(设置广播厂家自定义数据中Mac地址的大端序或小端序)

 @param type type
 0：Little endian (default)(小端序 （默认）)
 1：Big endian(大端序)
 */
-(void)setSetMACAddressType:(int)type;

/**
 Set up the module's service and feature services(设置模块的服务和特征服务)

 @param serverUUIDData server
 @param charateristicUUIDData charateristic
 @param type UUID length：
 0 : 16 bytes（default）
 1：2 bytes
 */
-(void)setBluetoothServerUUID:(NSData *)serverUUIDData charateristicUUID:(NSData *)charateristicUUIDData UUIDType:(int)type;

/**
 Set the master-slave mode of the module(设置模块的主从模式)

 @param type Value：
 0：Slave mode (default)(从机模式（默认）)
 1：Host mode(主机模式)
 */
-(void)setMCUModel:(int)type;

/**
 Set the module's automatic sleep time without connection(设置模块无连接的自动休眠时间)

 @param open Automatic sleep flag(自动睡眠标志位)：
 0：Do not turn on automatic sleep(不开启自动休眠)
 1：Turn on auto sleep, the module is not connected(开启自动休眠，模块没有连接)
 @param time Automatic sleep time (ms)(自动睡眠时间(ms))
 @param radio Whether to enable low frequency broadcast after sleep: (unit: ms)(睡眠后是否开启低频广播：（单位：ms）)
 0：Not open(不开启)
 1：Open(开启)
 @param interval 低频广播间隔时间,20~2000ms
 */
-(void)setAutoSleepTimeIsOpen:(BOOL)open autoSleepTime:(unsigned int)time isRadio:(BOOL)radio radioInterval:(int)interval;

/**
 Set to sleep(设置进入睡眠)

 @param radio Whether to enable low frequency broadcast after sleep: (in ms)(睡眠后是否开启低频广播：（单位 ms）)
 0：Not open(不开启)
 1：Open(开启)
 @param interval 低频广播间隔时间,20~2000ms
 */
-(void)setGotoSleepIsRadio:(BOOL)radio interval:(int)interval;

/**
 Set module wake up(设置模块唤醒)
 */
-(void)setMCUWakeUp;

/**
 Set the current time of the system(设置系统当前时间)
 @param enable
 NO: In addition to the ability to turn off the time function, you can save part of the current (default)(除能，关闭时间功能，可省部分电流（默认）)
 YES:Enable, turn on the timer function timer(使能，开启计时功能定时器)
 */
-(void)setMCUNowDateWithEnable:(BOOL)enable;

/**
 Setting CID, VID, PID（设置CID、VID、PID）

 @param setC Whether to set the CID(是否设置CID)
 @param setV Whether to set the VID(是否设置VID)
 @param setP Whether to set the PID(是否设置PID)
 @param cid Product Type ID: Less than 65536(产品类型ID：小于65536)
 @param vid Manufacturer ID: less than 65536(厂家ID：小于65536)
 @param pid Product ID: Less than 65536(产品ID：小于65536)
 */
-(void)setC_V_P_IDWithIsSetCID:(BOOL)setC isSetVID:(BOOL)setV isSetPID:(BOOL)setP CID:(unsigned int)cid VID:(unsigned int)vid PID:(unsigned int)pid;

/**
 Set module communication mode
 设置模块通信模式

 @param mode communication mode（通信模式）
 */
-(void)setCommunicationMode:(ELCommunicationModeType)mode;

/**
 Set module restart
 设置模块重启
 */
-(void)setMCURestart;

/**
 Set factory reset
 设置恢复出厂设置
 */
-(void)setFactoryDataReset;

/**
 Set the Bluetooth connection status（设置蓝牙连接状态）

 @param disconnect Active disconnect flag（主动断开连接标志位）
 1：Disconnect immediately（立刻断开连接）
 0：Not disconnected（不断开连接）
 */
-(void)setDisconnected:(BOOL)disconnect;

/**
 Send decoding key（发送解码密钥）

 @param data The length of the decoding key is 19, the first 16 are keys, and the last 3 are random texts. You need to save this value on the app and MCU to generate a one-time password. （解码密钥的长度为19,前16个为密钥，后3个为随机文,需要在app端和MCU端保存这个值，用于生成一次性密码）
 */
- (void)setKeyWithData:(NSData *)data;

/// Request device authorization(请求设备授权)
/// @param interval 时间截
-(void)requestDeviceAuthorization:(NSInteger)interval;


#pragma mark ============ Bluetooth WIFI calling method(蓝牙WIFI调用方法) ==============

/**
 WIFI initiate connection and disconnect(WIFI 发起连接、断开连接)

 @param connect YES: initiate connection NO: disconnect(YES:发起连接 NO:断开连接)
 */
-(void)bleWifiSetupWifiConnect:(BOOL)connect;

/**
 Set WIFI access URL(设置WIFI访问URL)
 
 @param url url（Not more than 56chars(不超过56chars)）
 */
-(void)bleWifiSetWifiURL:(NSString *)url;

/**
 Set Wifi access port number(设置Wifi访问端口号)
 
 @param port 端口号
 */
-(void)bleWifiSetPort:(int)port;

/**
 Set DTIM interval(设置DTIM间隔)

 @param interval 间隔
 */
-(void)bleWifiSetDTIMInterval:(int)interval;

/**
 Set WIFI password(设置WIFI密码)
 
 @param pwd WIFI password (8 ~ 56 chars)(WIFI密码(8~56 个chars))
 */
-(void)bleWifiSetWifiPwd:(NSString *)pwd;

/**
 Set up connected WIFI(设置连接的WIFI)

 @param macData wifi MAC (little endian)(wifi的MAC（小端序）)
 */
-(void)bleWifiSetConnectWifiMac:(NSData *)macData;

@end
NS_ASSUME_NONNULL_END

